//
//@File    :	13.10_usebrass2.cpp
//@Time    :	2021/09/19 11:53:14
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	polymorpgic example
//

//complie with brass.cpp
//-基类指针可以在不进行显式类型转换的情况下指向派生类对象
//-基类引用可以在不进行显示类型转换的情况引用派生类对象
//基类指针或引用只能用于调用基类方法,不能调用派生类

//BrassPlus Hoggy("Hoatito Hogg", 382288, 3000.00);
//Brass * pb=&Hoggy;//可以
//Brass & rb=Hoggy;//可以
//pb->ViewAcct();
//为虚函数时,根据对象类型选择
//非虚函数时,调用Brass::ViewAcct();

//1.编译器对非虚方法使用静态联编
//2.编译器对虚方法使用动态联编
//静态联编效率更高,为默认选择
#include <iostream>
#include <string>
#include"13.7_brass.h"
const int CLIENTS=4;

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;

    Brass *p_clients[CLIENTS];
    std::string temp;
    long tempnum;
    double tempbal;
    char kind;

    for (int i = 0; i < CLIENTS; i++)
    {
        cout<<"Enter client's name: ";
        getline(cin,temp);
        cout<<"Enter client's account number: ";
        cin>>tempnum;
        cout<<"Enter opening balance: $";
        cin>>tempbal;
        cout<<"Enter 1 for Brass Account or "
            <<"2 for BrassPlus Account: ";
        while (cin>>kind&&(kind!='1'&&kind!='2'))
        {
            cout<<"Enter either 1 or 2: ";
        }
        //输入'1'则使用Brass类
        if (kind=='1')
        {
            p_clients[i]=new Brass(temp,tempnum,tempbal);
        }
        //输入'2'则使用BrassPlus类
        else
        {
            double tmax,trate;
            cout<<"Enter the overfraft limit: $";
            cin>>tmax;
            cout<<"Enter the interest rate "
                <<"as a decimal fraction: ";
            cin>>trate;
            p_clients[i]=new BrassPlus(temp,tempnum,tempbal,tmax,trate);
    
        }
        while (cin.get()!='\n')
        {
            continue;
        }
    }
    cout<<endl;
    //多态性
    //如果数组成员指向的是Brass对象,则调用Brass::VieAcct()
    //如果指向的是BrassPlus对象,则调用BrassPlus::ViewAcct()
    for (int i = 0; i < CLIENTS; i++)
    {
        p_clients[i]->ViewAcct();
        cout<<endl;
    }
    
    for (int i = 0; i < CLIENTS; i++)
    {
        delete p_clients[i];//free memory
    }
    cout<<"Done.\n";
    system("pause");
    return 0;
}

//虚函数表(virtual function table,vtbl)

//每个对象都有一个隐藏的指针成员vptr,它指向类的虚函数表
//虚函数表是保存了虚函数地址的数组
//派生类未重新定义的函数在虚函数表中将保留基类中函数的地址
